package client.order;


import client.common.dto.SubmitOrderDTO;
import client.common.result.MaterialPageResult;
import client.common.result.Result;
import client.common.vo.MaterialVO;
import lombok.Data;
import remote.service.MaterialService;
import remote.service.OrderService;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.*;

/**
 * 主类，负责显示主窗口和管理订单提交。
 */
public class SubmitOrderForm extends JFrame {
    
    private OrderTableModel tableModel;
    private JTable table;
    private JButton addButton;
    private JButton removeButton;
    private JRadioButton inButton;
    private JRadioButton outButton;
    private JButton submitButton;
    private OrderService orderService = new OrderService() {
    };
    // 模拟物料列表，实际应从后台获取
    private List<MaterialVO> materialVOS;
    private MaterialService materialService = new MaterialService() {
    };
    
    public SubmitOrderForm() {
//        // 初始化物料列表
//        MaterialVOs = getMaterialList();
        
        // 设置窗口属性
        setTitle("物料出入库订单提交");
        setSize(800, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null);
        
        
        // 创建主面板
        JPanel panel = new JPanel(new BorderLayout());
        
        // 创建表格模型和表格
        tableModel = new OrderTableModel(materialVOS);
        table = new JTable(tableModel);
        table.setFillsViewportHeight(true);
        table.setRowHeight(25);
        
        // 设置物料ID列为不可编辑
        TableColumn MaterialVOIdColumn = table.getColumnModel().getColumn(0);
        MaterialVOIdColumn.setPreferredWidth(100);
        
        // 设置物料名称列为不可编辑（通过对话框添加物料）
        TableColumn MaterialVONameColumn = table.getColumnModel().getColumn(1);
        MaterialVONameColumn.setPreferredWidth(300);
        
        // 数量列设置为数字输入
        TableColumn quantityColumn = table.getColumnModel().getColumn(2);
        quantityColumn.setCellEditor(new QuantityCellEditor());
        quantityColumn.setPreferredWidth(100);
        
        // 添加表格到滚动面板
        JScrollPane tableScrollPane = new JScrollPane(table);
        panel.add(tableScrollPane, BorderLayout.CENTER);
        
        // 创建底部面板（添加/删除按钮和提交按钮）
        JPanel bottomPanel = new JPanel(new BorderLayout());
        
        // 添加/删除按钮面板
        JPanel addRemovePanel = new JPanel();
        addButton = new JButton("添加物料");
        removeButton = new JButton("删除选中物料");
        addRemovePanel.add(addButton);
        addRemovePanel.add(removeButton);
        bottomPanel.add(addRemovePanel, BorderLayout.WEST);
        
        // 入库/出库选择和提交按钮面板
        JPanel inOutSubmitPanel = new JPanel();
        
        ButtonGroup inOutGroup = new ButtonGroup();
        inButton = new JRadioButton("入库");
        outButton = new JRadioButton("出库");
        inOutGroup.add(inButton);
        inOutGroup.add(outButton);
        inButton.setSelected(true); // 默认选择入库
        
        submitButton = new JButton("提交订单");
        
        inOutSubmitPanel.add(inButton);
        inOutSubmitPanel.add(outButton);
        inOutSubmitPanel.add(submitButton);
        
        bottomPanel.add(inOutSubmitPanel, BorderLayout.EAST);
        
        panel.add(bottomPanel, BorderLayout.SOUTH);
        
        // 添加主面板到窗口
        add(panel);
        
        // 添加按钮事件
        addButton.addActionListener(e -> openAddMaterialVODialog());
        removeButton.addActionListener(e -> removeSelectedRows());
        submitButton.addActionListener(e -> handleSubmitOrder());
        
        // 显示窗口
        setVisible(true);
    }
    
    /**
     * 主方法，启动应用。
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SubmitOrderForm submitOrderForm = new SubmitOrderForm();
            submitOrderForm.setVisible(true);
        });
    }
    
    /**
     * 打开添加物料的对话框。
     */
    private void openAddMaterialVODialog() {
        AddMaterialVODialog dialog = new AddMaterialVODialog(this, materialVOS);
        dialog.setVisible(true);
        // 获取添加的物料
        OrderMaterialVO selectedMaterialVO = dialog.getSelectedOrderMaterialVO();
        if (selectedMaterialVO != null) {
            // 检查是否已存在相同物料，若存在则更新数量
            boolean exists = false;
            for (int i = 0; i < tableModel.getRowCount(); i++) {
                OrderMaterialVO om = tableModel.getOrderMaterialVOAt(i);
                if (om.getMaterialVOId().equals(selectedMaterialVO.getMaterialVOId())) {
                    om.setQuantity(om.getQuantity() + selectedMaterialVO.getQuantity());
                    tableModel.fireTableRowsUpdated(i, i);
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                tableModel.addOrderMaterialVO(selectedMaterialVO);
            }
        }
    }
    
    /**
     * 删除选中的物料行。
     */
    private void removeSelectedRows() {
        int[] selectedRows = table.getSelectedRows();
        if (selectedRows.length == 0) {
            JOptionPane.showMessageDialog(this, "请选择要删除的物料行。", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        // 从后向前删除，避免索引问题
        for (int i = selectedRows.length - 1; i >= 0; i--) {
            tableModel.removeRow(selectedRows[i]);
        }
    }
    
    /**
     * 处理提交订单的逻辑。
     */
    private void handleSubmitOrder() {
        // 结束编辑
        if (table.isEditing()) {
            TableCellEditor editor = table.getCellEditor();
            if (editor != null) {
                editor.stopCellEditing();
            }
        }
        
        List<OrderMaterialVO> orderMaterialVOs = tableModel.getOrderMaterialVOs();
        if (orderMaterialVOs.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请至少添加一条物料信息。", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        // 检查每条物料的有效性
        for (OrderMaterialVO om : orderMaterialVOs) {
            if (om.getMaterialVOId() == null) {
                JOptionPane.showMessageDialog(this, "所有物料名称均需选择。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            if (om.getQuantity() == null || om.getQuantity() <= 0) {
                JOptionPane.showMessageDialog(this, "所有物料的数量需为正整数。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
        }
        
        // 获取入库/出库选择
        int inOut = inButton.isSelected() ? 0 : 1;
        
        // 构建 SubmitOrderDto
        Map<Long, Long> MaterialVOMap = new HashMap<>();
        for (OrderMaterialVO om : orderMaterialVOs) {
            MaterialVOMap.put(om.getMaterialVOId(), om.getQuantity().longValue());
        }
        
        // 转换为 JSON（使用简单的字符串拼接，实际应使用 JSON 库如 Gson 或 Jackson）
        String MaterialVOMapJson = convertMapToJson(MaterialVOMap);
        
        SubmitOrderDTO submitOrderDto = new SubmitOrderDTO(MaterialVOMapJson, inOut);
        
        // 调用订单提交服务（这里模拟调用）
        Result result = orderService.submitOrder(submitOrderDto);
        
        // 显示结果
        if (result.isSuccess()) {
            JOptionPane.showMessageDialog(this, "订单提交成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
            tableModel.clearAllRows();
        } else {
            JOptionPane.showMessageDialog(this, "订单提交失败: " + result.getMessage(), "失败", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    /**
     * 将 Map 转换为 JSON 字符串（简单实现，建议使用 Gson 或 Jackson）。
     */
    private String convertMapToJson(Map<Long, Long> map) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        Iterator<Map.Entry<Long, Long>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Long, Long> entry = iterator.next();
            sb.append(entry.getKey()).append(":").append(entry.getValue());
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }
    
    /**
     * 订单中的单个物料条目。
     */
    @Data
    class OrderMaterialVO {
        private Long MaterialVOId;
        private String materialName;
        private Integer quantity;
        
        public OrderMaterialVO(Long MaterialVOId, String materialName, Integer quantity) {
            this.MaterialVOId = MaterialVOId;
            this.materialName = materialName;
            this.quantity = quantity;
        }
        
    }
    
    /**
     * 表格模型，管理订单物料的数据。
     */
    class OrderTableModel extends AbstractTableModel {
        
        private final String[] columnNames = {"物料ID", "物料名称", "数量"};
        private final List<OrderMaterialVO> orderMaterialVOs;
        private final List<MaterialVO> MaterialVOs;
        
        public OrderTableModel(List<MaterialVO> MaterialVOs) {
            this.MaterialVOs = MaterialVOs;
            this.orderMaterialVOs = new ArrayList<>();
        }
        
        /**
         * 添加 OrderMaterialVO 到表格。
         */
        public void addOrderMaterialVO(OrderMaterialVO om) {
            orderMaterialVOs.add(om);
            fireTableRowsInserted(orderMaterialVOs.size() - 1, orderMaterialVOs.size() - 1);
        }
        
        /**
         * 移除指定行的数据。
         */
        public void removeRow(int rowIndex) {
            orderMaterialVOs.remove(rowIndex);
            fireTableRowsDeleted(rowIndex, rowIndex);
        }
        
        /**
         * 获取所有订单物料。
         */
        public List<OrderMaterialVO> getOrderMaterialVOs() {
            return orderMaterialVOs;
        }
        
        /**
         * 获取指定行的订单物料。
         */
        public OrderMaterialVO getOrderMaterialVOAt(int rowIndex) {
            return orderMaterialVOs.get(rowIndex);
        }
        
        /**
         * 清空所有订单物料。
         */
        public void clearAllRows() {
            orderMaterialVOs.clear();
            fireTableDataChanged();
        }
        
        @Override
        public int getRowCount() {
            return orderMaterialVOs.size();
        }
        
        @Override
        public int getColumnCount() {
            return columnNames.length;
        }
        
        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
        
        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            OrderMaterialVO om = orderMaterialVOs.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    return om.getMaterialVOId();
                case 1:
                    // 根据物料ID获取名称
                    return om.getMaterialName();
                case 2:
                    return om.getQuantity();
                default:
                    return null;
            }
        }
        
        
        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            OrderMaterialVO om = orderMaterialVOs.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    // 物料ID列不可编辑
                    break;
                case 1:
                    // 物料名称列不可编辑，因为通过对话框添加
                    break;
                case 2:
                    try {
                        Integer quantity = Integer.parseInt(aValue.toString());
                        om.setQuantity(quantity);
                    } catch (NumberFormatException e) {
                        om.setQuantity(null);
                    }
                    fireTableCellUpdated(rowIndex, columnIndex);
                    break;
            }
        }
        
        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            // 仅数量列可编辑
            return columnIndex == 2;
        }
        
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex == 0) {
                return Long.class;
            } else if (columnIndex == 2) {
                return Integer.class;
            } else {
                return String.class;
            }
        }
    }
    
    /**
     * 添加物料的对话框。
     */
    class AddMaterialVODialog extends JDialog {
        
        private final MaterialService materialService = new MaterialService() {
        }; // 初始化远程服务
        private JTextField searchField;
        private JButton searchButton;
        private JTable resultTable;
        private JButton addButton;
        private JButton cancelButton;
        private JButton firstPageButton;
        private JButton prevPageButton;
        private JButton nextPageButton;
        private JButton lastPageButton;
        private JLabel pageInfoLabel;
        private SearchResultTableModel tableModel;
        private List<MaterialVO> materialVOs;
        private List<MaterialVO> searchResults;
        private OrderMaterialVO selectedOrderMaterialVO;
        private int currentPage = 1;
        private int totalPages = 1;
        private int pageSize = 13; // 每页显示的物料数量
        private boolean isSearching = false; // 标识是否在进行搜索
        
        public AddMaterialVODialog(JFrame parent, List<MaterialVO> materialVOs) {
            super(parent, "添加物料", true);
            this.materialVOs = materialVOs;
            this.selectedOrderMaterialVO = null;
            
            setSize(600, 400);
            setLocationRelativeTo(parent);
            setLayout(new BorderLayout());
            
            // 搜索面板
            JPanel searchPanel = new JPanel(new FlowLayout());
            searchPanel.add(new JLabel("搜索物料:"));
            searchField = new JTextField(20);
            searchPanel.add(searchField);
            searchButton = new JButton("查询");
            searchPanel.add(searchButton);
            add(searchPanel, BorderLayout.NORTH);
            
            // 结果表格
            tableModel = new SearchResultTableModel();
            resultTable = new JTable(tableModel);
            resultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(resultTable);
            add(scrollPane, BorderLayout.CENTER);
            
            // 按钮面板
            JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            addButton = new JButton("添加");
            cancelButton = new JButton("取消");
            buttonPanel.add(addButton);
            buttonPanel.add(cancelButton);
            add(buttonPanel, BorderLayout.SOUTH);
            
            // 创建分页面板并添加到对话框
            JPanel paginationPanel = createPaginationPanel();
            add(paginationPanel, BorderLayout.SOUTH);
            
            // 创建一个新的面板来包含按钮和分页
            JPanel mainPanel = new JPanel(new BorderLayout());
            mainPanel.add(buttonPanel, BorderLayout.SOUTH);
            mainPanel.add(paginationPanel, BorderLayout.NORTH);
            
            // 将主面板添加到对话框
            add(mainPanel, BorderLayout.SOUTH);
            
            
            // 按钮事件
            searchButton.addActionListener(e -> performSearch());
            addButton.addActionListener(e -> addSelectedMaterialVO());
            cancelButton.addActionListener(e -> dispose());
            
            // 回车键触发搜索
            searchField.addActionListener(e -> performSearch());
            
            // 初始加载所有物料信息
            loadMaterials();
        }
        
        /**
         * 创建分页面板
         */
        private JPanel createPaginationPanel() {
            JPanel paginationPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 10));
            
            // 首页按钮
            firstPageButton = new JButton("首页");
            firstPageButton.addActionListener(e -> {
                if (currentPage != 1) {
                    currentPage = 1;
                    loadMaterials();
                }
            });
            paginationPanel.add(firstPageButton);
            
            // 上一页按钮
            prevPageButton = new JButton("上一页");
            prevPageButton.addActionListener(e -> {
                if (currentPage > 1) {
                    currentPage--;
                    loadMaterials();
                }
            });
            paginationPanel.add(prevPageButton);
            
            // 下一页按钮
            nextPageButton = new JButton("下一页");
            nextPageButton.addActionListener(e -> {
                if (currentPage < totalPages) {
                    currentPage++;
                    loadMaterials();
                }
            });
            paginationPanel.add(nextPageButton);
            
            // 末页按钮
            lastPageButton = new JButton("末页");
            lastPageButton.addActionListener(e -> {
                if (currentPage != totalPages) {
                    currentPage = totalPages;
                    loadMaterials();
                }
            });
            paginationPanel.add(lastPageButton);
            
            // 页码信息标签
            pageInfoLabel = new JLabel("第 1 页 / 共 1 页");
            pageInfoLabel.setFont(pageInfoLabel.getFont().deriveFont(14f));
            paginationPanel.add(pageInfoLabel);
            
            return paginationPanel;
        }
        
        private void loadMaterials() {
            if (isSearching) { // 如果正在搜索，调用模糊查询接口
                performFuzzyQuery(currentPage);
            } else { // 否则，调用正常的分页加载接口
                MaterialPageResult materialResult = materialService.getMaterialByPage(currentPage, pageSize, false);
                if (materialResult != null && materialResult.getData() != null) {
                    List<MaterialVO> materials = materialResult.getData().getData(); // 当前页的物料列表
                    int totalRecords = materialResult.getData().getTotal(); // 总记录数
                    
                    // 更新总页数和当前页码
                    totalPages = (int) Math.ceil((double) totalRecords / pageSize);
                    pageInfoLabel.setText("第 " + currentPage + " 页 / 共 " + totalPages + " 页");
                    searchResults = materials; // 更新 searchResults
                    // 更新表格的数据
                    tableModel.setSearchResults(materials);
                } else {
                    JOptionPane.showMessageDialog(this, "无法加载物料信息", "错误", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
        
        private void performFuzzyQuery(int page) {
            String query = searchField.getText().trim().toLowerCase();
            // 调用后端接口模糊搜索
            MaterialPageResult materialResult = materialService.fuzzyQueryMaterial(query, page, pageSize, false);
            if (materialResult != null && materialResult.getData() != null) {
                List<MaterialVO> materials = materialResult.getData().getData(); // 当前页的物料列表
                int totalRecords = materialResult.getData().getTotal(); // 总记录数
                
                // 更新总页数和当前页码
                totalPages = (int) Math.ceil((double) totalRecords / pageSize);
                pageInfoLabel.setText("第 " + currentPage + " 页 / 共 " + totalPages + " 页");
                
                // 更新表格的数据
                tableModel.setSearchResults(materials);
            } else {
                JOptionPane.showMessageDialog(this, "无法加载物料信息", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
        
        /**
         * 执行模糊搜索。
         */
        private void performSearch() {
            String query = searchField.getText().trim().toLowerCase();
            if (query.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请输入搜索关键词。", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            isSearching = true; // 标记为搜索状态
            currentPage = 1; // 每次搜索都从第一页开始
            
            // 调用后端接口模糊搜索
            MaterialPageResult materialResult = materialService.fuzzyQueryMaterial(query, currentPage, pageSize, false);
            if (materialResult != null && materialResult.getData() != null) {
                List<MaterialVO> materials = materialResult.getData().getData(); // 当前页的物料列表
                int totalRecords = materialResult.getData().getTotal(); // 总记录数
                
                // 更新总页数和当前页码
                totalPages = (int) Math.ceil((double) totalRecords / pageSize);
                pageInfoLabel.setText("第 " + currentPage + " 页 / 共 " + totalPages + " 页");
                
                // 更新表格的数据
                tableModel.setSearchResults(materials);
                searchResults = materials; // 更新 searchResults
            } else {
                JOptionPane.showMessageDialog(this, "未找到匹配的物料。", "提示", JOptionPane.INFORMATION_MESSAGE);
            }
        }
        
        
        /**
         * 添加选中的物料到主表格。
         */
        private void addSelectedMaterialVO() {
            int selectedRow = resultTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请选择一个物料。", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }
            
            MaterialVO selectedMaterialVO = searchResults.get(selectedRow);
            
            // 输入数量
            String quantityStr = JOptionPane.showInputDialog(this, "请输入数量:", "输入数量", JOptionPane.PLAIN_MESSAGE);
            if (quantityStr == null) {
                return; // 用户取消
            }
            quantityStr = quantityStr.trim();
            if (quantityStr.isEmpty()) {
                JOptionPane.showMessageDialog(this, "数量不能为空。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            int quantity;
            try {
                quantity = Integer.parseInt(quantityStr);
                if (quantity <= 0) {
                    throw new NumberFormatException("数量必须为正整数。");
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "请输入有效的正整数数量。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            
            // 创建 OrderMaterialVO 对象
            selectedOrderMaterialVO = new OrderMaterialVO(selectedMaterialVO.getId(), selectedMaterialVO.getName(), quantity);
            
            // 关闭对话框
            dispose();
        }
        
        /**
         * 获取选中的 OrderMaterialVO。
         */
        public OrderMaterialVO getSelectedOrderMaterialVO() {
            return selectedOrderMaterialVO;
        }
        
        /**
         * 搜索结果的表格模型。
         */
        class SearchResultTableModel extends AbstractTableModel {
            
            private final String[] columnNames = {"物料ID", "物料名称"};
            private List<MaterialVO> searchResults = new ArrayList<>();
            
            public void setSearchResults(List<MaterialVO> searchResults) {
                this.searchResults = searchResults;
                fireTableDataChanged();
            }
            
            @Override
            public int getRowCount() {
                return searchResults.size();
            }
            
            @Override
            public int getColumnCount() {
                return columnNames.length;
            }
            
            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }
            
            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                MaterialVO m = searchResults.get(rowIndex);
                switch (columnIndex) {
                    case 0:
                        return m.getId();
                    case 1:
                        return m.getName();
                    default:
                        return null;
                }
            }
            
            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return false;
            }
        }
    }
    
    /**
     * 自定义数量单元格编辑器，限制为整数。
     */
    class QuantityCellEditor extends AbstractCellEditor implements TableCellEditor {
        
        private final JTextField textField = new JTextField();
        
        public QuantityCellEditor() {
            // 限制只能输入数字
            textField.addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e) {
                    char c = e.getKeyChar();
                    if (!Character.isDigit(c) && c != KeyEvent.VK_BACK_SPACE && c != KeyEvent.VK_DELETE) {
                        e.consume(); // 忽略非数字输入
                    }
                }
            });
        }
        
        @Override
        public Object getCellEditorValue() {
            String text = textField.getText();
            if (text.isEmpty()) {
                return null;
            }
            try {
                return Integer.parseInt(text);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            textField.setText(value != null ? value.toString() : "");
            return textField;
        }
    }
}
